package alpha.com.google.code.mechanic.janitor.ui;

import java.util.List;
import java.util.Set;

import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.property.Properties;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;

import alpha.com.google.code.mechanic.janitor.controller.ContextData;

import com.google.eclipse.mechanic.Task;

/**
 * The TaskCopyDialog is to allow the users to copy selected Tasks to a current Context
 * or to a new Context.
 * 
 * Last_edited: Nov 6, 2014
 *
 * @History
 * 1. Add code to check Context name duplication.
 * @author jingjiejiang
 * @edited Nov 6, 2014
 * 1) add a private field: ContextData ctxData
 * 2) add checking code in the method: modifyText(ModifyEvent e)
 *
 * @author jingjiejiang
 * @since Apr 11, 2014
 * @author jingjiejiang
 * @since Aug 13, 2014
 */
public class TaskCopyDialog extends Dialog {
  
  // The title of the dialog.
  private static final String TASK_COPY_DIALOG_TITLE = "Copy Tasks";
  
  private Text textNewCtxName;
  private Table tblSrcTasks;
  private CheckboxTableViewer chkboxSrcTask;
  // The button indicates that whether users want to copy the selected Tasks
  // to one of existing Contexts.
  private Button btnRadioCurCtx;
  // The button indicates that whether users want to copy the selected Tasks
  // to a new Context.
  private Button btnRadioNewCtx;
  private Combo comboCurCtxList;
  
  // The current Tasks used in the system.
  private Set<Task> setTask;
  // The current user defined Context in the system.
  private List<String> listCtx;
  
  // The selected Tasks that needed to be copied.
  private Object[] selTask;
  // The name of the Context that the selected Tasks will be copied to.
  private String copyCtxName;
  // The value indicates that whether the selected Tasks will be copied to
  // a new Context.
  boolean isNewCtx;
  
  private ContextData ctxData;

  /**
   * Create the dialog.
   * @param parentShell
   */
  public TaskCopyDialog(Shell parentShell, Set<Task> setTask,
      List<String> listCtx) {
    super(parentShell);
    this.setTask = setTask;
    this.listCtx = listCtx;
    
    ctxData = new ContextData();
    try {
      ctxData.readContextsFile();
    } catch (Exception e) {
      MessageDialog.openError(getParentShell(), "Couldn't read the "
          + "context.con file.", e.getMessage());
    }
  }
  
  public String getCopyCtxName() {
    return copyCtxName;
  }
  
  public void setCopyCtxName(String copyCtxName) {
    this.copyCtxName = copyCtxName;
  }
  
  public boolean isNewCtx() {
    return isNewCtx;
  }

  public void setNewCtx(boolean isNewCtx) {
    this.isNewCtx = isNewCtx;
  }
  
  @Override
  protected void configureShell(Shell shell) {
    super.configureShell(shell);
    if (TASK_COPY_DIALOG_TITLE != null) {
      shell.setText(TASK_COPY_DIALOG_TITLE);
    }
  }
  
  @Override
  public void create() {
    super.create();
    getButton(IDialogConstants.OK_ID).setEnabled(false);
  }

  /**
   * Create contents of the dialog.
   * @param parent
   */
  @Override
  protected Control createDialogArea(Composite parent) {
    
    Composite container = (Composite) super.createDialogArea(parent);
    
    Composite composite = new Composite(container, SWT.NONE);
    GridData gd_composite = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
    gd_composite.heightHint = 338;
    gd_composite.widthHint = 340;
    composite.setLayoutData(gd_composite);
    
    Label lblSrcTasks = new Label(composite, SWT.NONE);
    lblSrcTasks.setBounds(0, 0, 239, 14);
    lblSrcTasks.setText("Select the Task files that you want to copy:");
    
    createChkboxTblSrcTask(composite);
    
    Composite compoDstn = new Composite(composite, SWT.BORDER);
    compoDstn.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.NORMAL));
    compoDstn.setBounds(0, 262, 339, 76);
    
    Label lblDstn = new Label(compoDstn, SWT.NONE);
    lblDstn.setBounds(3, 0, 69, 14);
    lblDstn.setText("Destination:");
    
    createComboCtxList(compoDstn);
    createBtnCurCtx(compoDstn);
    createBtnNewCtx(compoDstn);
    createTextNewCtx(compoDstn);
    
    Button btnSelAll = new Button(composite, SWT.NONE);
    btnSelAll.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        chkboxSrcTask.setAllChecked(true);
      }
    });
    btnSelAll.setBounds(0, 231, 94, 28);
    btnSelAll.setText("Select All");
    
    Button btnDeselAll = new Button(composite, SWT.NONE);
    btnDeselAll.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        chkboxSrcTask.setAllChecked(false);
      }
    });
    btnDeselAll.setBounds(92, 231, 94, 28);
    btnDeselAll.setText("Deselect All");
    
    initTaskDataBindings();
    
    return container;
  }
  
  private void createBtnNewCtx (Composite composite) {
    
    btnRadioNewCtx = new Button(composite, SWT.RADIO);
    btnRadioNewCtx.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        
        boolean isseled = btnRadioNewCtx.getSelection();
        if (isseled) {
          textNewCtxName.setBackground(new Color(null, 255, 255, 255));
          textNewCtxName.setEditable(true);
          btnRadioCurCtx.setSelection(false);
          comboCurCtxList.setBackground(new Color(null, 204, 205, 207));
          comboCurCtxList.clearSelection();
          comboCurCtxList.setEnabled(false);
          
          getButton(IDialogConstants.OK_ID).setEnabled(false);
        }
      }
    });
    btnRadioNewCtx.setBounds(3, 47, 137, 18);
    btnRadioNewCtx.setText("To a new Context:");
    btnRadioNewCtx.setSelection(false);
  }
  
  private void createBtnCurCtx (Composite composite) {
    
    btnRadioCurCtx = new Button(composite, SWT.RADIO);
    btnRadioCurCtx.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        boolean isseled = btnRadioCurCtx.getSelection();
        if (isseled) {
//          btnRadioCurCxt.setEnabled(true);
          comboCurCtxList.setEnabled(true);
          comboCurCtxList.setBackground(new Color(null, 255, 255, 255));
          btnRadioNewCtx.setSelection(false);    
          textNewCtxName.setText("");
          textNewCtxName.setBackground(new Color(null, 204, 205, 207));
          textNewCtxName.setEditable(false);
          
          getButton(IDialogConstants.OK_ID).setEnabled(false);
        }
      }
    });
    btnRadioCurCtx.setBounds(3, 20, 148, 18);
    btnRadioCurCtx.setText("To an existing Context:");
    btnRadioCurCtx.setSelection(true);
  }
  
  private void createComboCtxList (Composite composite) {
    
    String[] ctxs = listCtx.toArray(new String[listCtx.size()]);
    
    comboCurCtxList = new Combo(composite, SWT.READ_ONLY);
    comboCurCtxList.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        if (!comboCurCtxList.getText().equals("")) {
          getButton(IDialogConstants.OK_ID).setEnabled(true);
        }
        else {
          getButton(IDialogConstants.OK_ID).setEnabled(false);
        }
      }
    });

    comboCurCtxList.setBounds(157, 19, 180, 22);
    comboCurCtxList.setItems(ctxs);
  }
  
  private void createTextNewCtx (Composite composite) {
    
    textNewCtxName = new Text(composite, SWT.BORDER);
    textNewCtxName.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        
        String name = textNewCtxName.getText();
        boolean isenable = false;
        
        if(!name.equals("")) {
          if (ctxData.getContextsCollector().isValidCtxName(name)) {
            isenable = true;
          } else {
            MessageDialog.openError(getParentShell(), "Error", "There "
                + "already exist a Context with the same name. Please "
                + "specify another name for the new Context."); 
          }
        }
      
        getButton(IDialogConstants.OK_ID).setEnabled(isenable);
      }
    });
    textNewCtxName.setBounds(131, 47, 203, 19);
    textNewCtxName.setEditable(false);
    textNewCtxName.setBackground(new Color(null, 204, 205, 207));
  }
  
  /**
   * Create the checkbox table of source Tasks.
   *
   * @param composite
   */
  private void createChkboxTblSrcTask (Composite composite) {
    
    chkboxSrcTask = CheckboxTableViewer.newCheckList(composite, SWT.BORDER | SWT.FULL_SELECTION);
    tblSrcTasks = chkboxSrcTask.getTable();
    tblSrcTasks.setHeaderVisible(true);
    tblSrcTasks.setBounds(0, 21, 340, 208);
    
    TableViewerColumn tblViewerClmnTskName = new TableViewerColumn(chkboxSrcTask, SWT.NONE);
    TableColumn tblClmnTaskNames = tblViewerClmnTskName.getColumn();
    tblClmnTaskNames.setWidth(320);
    tblClmnTaskNames.setText("      Task Name");
  }
  
  protected void initTaskDataBindings() {

    ObservableSetContentProvider setContentProvider = new ObservableSetContentProvider();
    IObservableMap observeMap = PojoObservables.observeMap(setContentProvider.getKnownElements(), Task.class, "title");
    chkboxSrcTask.setLabelProvider(new ObservableMapLabelProvider(observeMap));
    chkboxSrcTask.setContentProvider(setContentProvider);
    IObservableSet selfSet = Properties.selfSet(Task.class).observe(setTask);
    chkboxSrcTask.setInput(selfSet);
  }
  
  /**
   * Get the name of the Context that the selected Tasks will be copied to.
   *
   * @return
   */
  public void getContextName () {
    
    setNewCtx(btnRadioNewCtx.getSelection());
    
    if (isNewCtx) {
      setCopyCtxName(textNewCtxName.getText());
    }
    else {
      setCopyCtxName(comboCurCtxList.getText());
    }
    
  }
  
  public Object[] getSelTaskNames () {
   
   // Object[] seltasks = chkboxSrcTask.getCheckedElements();

   return selTask;
  }

  /**
   * Create contents of the button bar.
   * @param parent
   */
  @Override
  protected void createButtonsForButtonBar(Composite parent) {
    createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
        true);
    createButton(parent, IDialogConstants.CANCEL_ID,
        IDialogConstants.CANCEL_LABEL, false);
  }

  /**
   * Return the initial size of the dialog.
   */
  @Override
  protected Point getInitialSize() {
    return new Point(359, 426);
  }
  
  @Override
  protected void okPressed() {
    
    selTask = chkboxSrcTask.getCheckedElements();
    getContextName();
    
    super.okPressed();
  }

}
